package com.ea.report.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ea.common.result.BizException;
import com.ea.common.result.ErrorCode;
import com.ea.report.mapper.DefaultCompanyConfMapper;
import com.ea.report.mapper.PropertiesInfoMapper;
import com.ea.report.mapper.ReportInfoMapper;
import com.ea.report.mapper.ReportPropertiesMapper;
import com.ea.report.pojo.dto.ReportPropertiesDto;
import com.ea.report.pojo.po.*;
import com.ea.report.pojo.po.shenshiResult.FaceData;
import com.ea.report.pojo.po.shenshiResult.ShenshiResult;
import com.ea.report.pojo.po.shenshiResult.ShenshiResultProperties;
import com.ea.report.pojo.po.vibraResult.*;
import com.ea.report.pojo.vo.IsAnalyzedVo;
import com.ea.report.service.ReportResultService;
import com.google.common.util.concurrent.AtomicDouble;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.util.*;
import java.util.stream.Collectors;

import static com.ea.report.pojo.po.vibraResult.VibraResultProperties.Extraversion;
import static com.ea.report.pojo.po.vibraResult.VibraResultProperties.Stability;

class Ref<T>
{
    public T value;
    public Ref(T aValue)
    {
        value = aValue;
    }
}

@Service
@Slf4j
public class ReportResultServiceImpl implements ReportResultService {
    @Resource
    ReportInfoMapper reportInfoMapper;
    @Resource
    PropertiesInfoMapper propertiesInfoMapper;
    @Resource
    ReportPropertiesMapper reportPropertiesMapper;
    @Resource
    DefaultCompanyConfMapper defaultCompanyConfMapper;

    @Override
    public void saveVibraResult(String uuid, String result, Boolean isSuccess) {
        // 根据uuid 查询出reportInfo
        // log.info("vibra result: {}", result);
        ReportInfo reportInfo = getReportInfo(uuid, 1);
        if (reportInfo == null) {
            return;
        }

        if (!isSuccess) {
            reportInfo.setStatus(4);
            reportInfo.setResultContent(result);
            updateDatabase(reportInfo);
            log.info("保存vibra结果失败，原因：{}", result);
            return;
        }

        // 截断字符串
        String head = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
        result = result.substring(result.indexOf(head) + head.length());
        // 解析 result
        // log.info("vibra result: {}", result);
        VibraResult resultObj;
        try {
            // 创建JAXBContext对象
            JAXBContext jaxbContext = JAXBContext.newInstance(VibraResult.class);

            // 创建Unmarshaller对象
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

            // 调用unmarshal方法将XML转化为对象
            resultObj = (VibraResult) unmarshaller.unmarshal(new StringReader(result));

        } catch (Exception e) {
            throw new BizException(ErrorCode.SYSTEM_ERROR_XML_PARSE_ERROR);
        }
        // propertiesName / defaultCompanyConfId -> propertiesId
        Map<String, Long> map = getPropertiesListToMap();
        Map<Long, DefaultCompanyConf> defaultCompanyConfMap = getDefaultCompanyConfMap();
        // 更新reportInfo
        List<ReportProperties> reportPropertiesList = new ArrayList<>(
                parseEmotionResultItemListToPo(
                        resultObj.getEmotionResultList(),
                        reportInfo.getReportId(),
                        reportInfo.getCompanyId(),
                        map,
                        defaultCompanyConfMap
                )
        );
        Ref<Double> fpsMax = new Ref<Double>(0.0);
        reportPropertiesList.add(
                parseFrequencyItemListToPo(
                        resultObj.getFrequencyResult(),
                        reportInfo.getReportId(),
                        reportInfo.getCompanyId(),
                        map,
                        fpsMax
                )
        );
        reportPropertiesList.add(
                parseSpectrumItemListToPo(
                        resultObj.getSpectrumResult(),
                        reportInfo.getReportId(),
                        reportInfo.getCompanyId(),
                        map,
                        fpsMax.value
                )
        );
        reportPropertiesList.add(
                parseMentalItemListToPo(
                        resultObj.getMentalResult(),
                        reportInfo.getReportId(),
                        reportInfo.getCompanyId(),
                        map
                )
        );
        updateDatabase(reportInfo, reportPropertiesList, 1);
    }

    private void updateDatabase(ReportInfo reportInfo) {
        updateDatabase(reportInfo, new ArrayList<>(), 1);
    }

    private Map<String, Long> getPropertiesListToMap() {
        // 获得properties Info
        List<PropertiesInfo> propertiesInfoList = propertiesInfoMapper.selectList(null);
        Map<String, Long> map = new HashMap<>();
        propertiesInfoList.forEach(propertiesInfo -> {
            if (propertiesInfo.getDefaultCompanyConfId() != null) {
                map.put(propertiesInfo.getDefaultCompanyConfId().toString(), propertiesInfo.getPropertiesId());
            } else if (propertiesInfo.getPropertiesName() != null) {
                map.put(propertiesInfo.getPropertiesName(), propertiesInfo.getPropertiesId());
            }
        });
        return map;
    }

    private ReportProperties parseMentalItemListToPo(MentalResult mentalResult, Long reportId, Long companyId, Map<String, Long> map) {
        ReportProperties reportProperties = new ReportProperties();
        reportProperties.setPropertiesId(map.get("心理变化率"));
        reportProperties.setReportId(reportId);
        reportProperties.setCompanyId(companyId);
        MentalRate pointList = parseMentalResultItemToPo(mentalResult.getBt());
        reportProperties.setValueText(JSONObject.toJSONString(pointList));
        reportProperties.setType(2);
        reportProperties.setCompare(0);
        return reportProperties;
    }

    private ReportProperties parseFrequencyItemListToPo(FrequencyResult frequencyResult, Long reportId, Long companyId, Map<String, Long> map, Ref<Double> fps) {
        ReportProperties reportProperties = new ReportProperties();
        double sum = 0.;
        int count = 0;
//        List<Point> frequencyItemList = new ArrayList<>();
        double x = 0f;
        for (FrequencyItem frequencyItem : frequencyResult.getFH_info()) {
            sum += frequencyItem.getM();
            if (frequencyItem.getM() > 0) {
                count++;
            }
            x = frequencyItem.getFpsMax();
        }
        fps.value = x;
        reportProperties.setPropertiesId(map.get("平均频率"));
        reportProperties.setReportId(reportId);
        reportProperties.setCompanyId(companyId);
        log.info("sum: {}, count: {}", sum, count);
        reportProperties.setValueInt((int) (sum * 1000));
        reportProperties.setType(1);
        reportProperties.setCompare(0);
        return reportProperties;
    }

    private MentalRate parseMentalResultItemToPo(List<MentalItem> bt) {
        MentalRate mentalRate = new MentalRate();
        List<Point> front = new ArrayList<>();
        List<Point> back = new ArrayList<>();

        int nq1 = -1;
        if (bt != null && !bt.isEmpty()) {
            int halfCount = bt.size() / 2;
            for (MentalItem item : bt) {
                // 根据excel其实E2, I2不需要，把E1，I1分为两部分根据nq1划分即可
                if (nq1 == -1 || nq1 == item.getNq1()) {
                    Point p = new Point(item.getE1() * 10., item.getI1() * 100.);
                    front.add(p);
                    nq1 = item.getNq1();
                } else {
                    Point p = new Point(item.getE1() * 10., item.getI1() * 100.);
                    back.add(p);
                }
            }
        }
        mentalRate.setFront(front);
        mentalRate.setBack(back);
        return mentalRate;
    }

    private ReportProperties parseSpectrumItemListToPo(SpectrumResult spectrumResult, Long reportId, Long companyId, Map<String, Long> map, Double fps) {
        ReportProperties reportProperties = new ReportProperties();
        reportProperties.setPropertiesId(map.get("心理测试频谱图"));
        reportProperties.setReportId(reportId);
        reportProperties.setCompanyId(companyId);

        List<Point> pointList = new ArrayList<>(parseSpectrumResultItemToPo(spectrumResult.getFH(), fps));
        reportProperties.setValueText(JSONObject.toJSONString(pointList));
        reportProperties.setType(2);
        reportProperties.setCompare(0);
        return reportProperties;
    }

    private List<Point> parseSpectrumResultItemToPo(List<SpectrumItem> spectrumItem, Double fps) {
        int index = 0;
        int countMinusOne = spectrumItem.size() - 1;
        List<Point> pointList = new ArrayList<>();

        for (SpectrumItem item : spectrumItem) {
            Point point = new Point();
            point.setX((double) index / (double)countMinusOne * fps);
            point.setY(item.getH());
            pointList.add(point);

            ++index;
        }

        return pointList;
    }

    private List<ReportProperties> parseEmotionResultItemListToPo(EmotionResult emotionResult, Long reportId, Long companyId, Map<String, Long> map, Map<Long, DefaultCompanyConf> defaultCompanyConfMap) {
        AtomicDouble pos = new AtomicDouble();
        AtomicDouble phy = new AtomicDouble();
        AtomicDouble neg = new AtomicDouble();
        AtomicDouble all = new AtomicDouble();

        Set<VibraResultProperties> propertiesSet = new HashSet<>();
        List<ReportProperties> reportPropertiesList = emotionResult.getItem().stream()
                .map(emotionResultItem -> {
                            Long propertiesId;
                    if (emotionResultItem.getId() == null) {
                        return null;
                    }
                    VibraResultProperties result = VibraResultProperties.getPropertiesById(emotionResultItem.getId());
                    if (propertiesSet.contains(result)) {
                        return null;
                    }
                    propertiesSet.add(result);

                            if (result == null) {
                                return null;
                            } else if (result.getDefaultCompanyConfId() != null) {
                                propertiesId = map.get(result.getDefaultCompanyConfId().toString());
                            } else if (result.getPropertiesName() != null) {
                                // 不是默认的属性，则使用 PropertiesId 查询map
                                propertiesId = map.get(result.getPropertiesName());
                            } else {
                                // 不是报告所需属性，直接返回空
                                return null;
                            }

                            if (result.getEmotionType() == 1) {
                                pos.addAndGet(emotionResultItem.getM().intValue());
                            } else if (result.getEmotionType() == 2) {
                                phy.addAndGet(emotionResultItem.getM().intValue());
                            } else if (result.getEmotionType() == 3) {
                                neg.addAndGet(emotionResultItem.getM().intValue());
                            }
                            all.addAndGet(emotionResultItem.getM().intValue());
                    return parseEmotionResultItemToPo(emotionResultItem, reportId, companyId, propertiesId, defaultCompanyConfMap, result);
                        }
                )
                .collect(Collectors.toList());

        reportPropertiesList.add(new ReportProperties(null, map.get("生理情绪"), reportId, companyId, (int) Math.round(phy.get() * 100.0D / all.get()), null, 0, 1));
        reportPropertiesList.add(new ReportProperties(null, map.get("正面情绪"), reportId, companyId, (int) Math.round(pos.get() * 100.0D / all.get()), null, 0, 1));
        reportPropertiesList.add(new ReportProperties(null, map.get("负面情绪"), reportId, companyId, (int) Math.round(neg.get() * 100.0D / all.get()), null, 0, 1));
        return reportPropertiesList;
    }

    ReportProperties parseEmotionResultItemToPo(EmotionResultItem emotionResultItem, Long reportId, Long companyId, Long propertiesId, Map<Long, DefaultCompanyConf> map, VibraResultProperties result) {
        ReportProperties reportProperties = new ReportProperties();
        reportProperties.setPropertiesId(propertiesId);
        reportProperties.setReportId(reportId);
        reportProperties.setCompanyId(companyId);
        try {
            int compare = 0;
            reportProperties.setValueInt(emotionResultItem.getM().intValue());
            if (result == Extraversion || result == Stability) {
                reportProperties.setValueInt((int) (emotionResultItem.getM() * 100));
            }
            reportProperties.setType(1);
            DefaultCompanyConf defaultCompanyConf = map.get(result.getDefaultCompanyConfIdOfValue());
            if (defaultCompanyConf != null) {
                int lowerValueInt = defaultCompanyConf.getLowerValueInt();
                int upperValueInt = defaultCompanyConf.getUpperValueInt();
                if (reportProperties.getValueInt() < lowerValueInt) {
                    compare = 2;
                } else if (reportProperties.getValueInt() > upperValueInt) {
                    compare = 1;
                }
            }
            reportProperties.setCompare(compare);
        } catch (Exception e) {
            throw new BizException(ErrorCode.SYSTEM_ERROR_XML_PARSE_ERROR);
        }

        // 呼吸指标不做处理
        if (reportProperties.getPropertiesId() == 14) {
            return null;
        }
        return reportProperties;
    }

    @Override
    public void saveShenshiResult(String uuid, String result, Boolean isSuccess) {
        // 根据uuid 查询出reportInfo
        ReportInfo reportInfo = getReportInfo(uuid, 2);
        if (reportInfo == null) {
            return;
        }

        if (!isSuccess) {
            reportInfo.setStatus(4);
            reportInfo.setResultContent(result);
            updateDatabase(reportInfo);
            log.info("保存shenshi结果失败，原因：{}", result);
            return;
        }

        // 解析 result
        // result = "{" + result + "}";
        // log.info("result: {}", result);
        try {
            // 作为数组解析
            List<ShenshiResult> resultObj;
            resultObj = JSONArray.parseArray(result, ShenshiResult.class);
            // 保存结果
            double hr = 0D;
            double br = 0D;
            double bpH = 0D;
            double bpL = 0D;
            double spo2 = 0D;
            int count = 0;

            for (ShenshiResult shenshiResult : resultObj) {
                // log.info("shenshiResult: {}", shenshiResult);
                FaceData faceData = shenshiResult.getData();
                if (faceData == null) {
                    continue;
                }
                count++;
                hr += faceData.getHr();
                br += faceData.getBr();
                bpH += faceData.getBp_h();
                bpL += faceData.getBp_l();
                spo2 += faceData.getSpo2();
            }

            Map<String, Long> map = getPropertiesListToMap();
            Map<Long, DefaultCompanyConf> companyConfMap = getDefaultCompanyConfMap();
            List<ReportProperties> reportPropertiesList = new ArrayList<>();
            // log.info("hr: {}, br: {}, bpH: {}, bpL: {}, spo2: {}", hr, br, bpH, bpL, spo2);

            if (count != 0) {
                reportPropertiesList.add(
                        parseShenshiToPo((int) hr / count, "心率", map, reportInfo.getReportId(), reportInfo.getCompanyId(), companyConfMap)
                );
                reportPropertiesList.add(
                        parseShenshiToPo((int) br / count, "呼吸", map, reportInfo.getReportId(), reportInfo.getCompanyId(), companyConfMap)
                );
                reportPropertiesList.add(
                        parseShenshiToPo((int) bpH / count, "血压-收缩压", map, reportInfo.getReportId(), reportInfo.getCompanyId(), companyConfMap)
                );
                reportPropertiesList.add(
                        parseShenshiToPo((int) bpL / count, "血压-舒张压", map, reportInfo.getReportId(), reportInfo.getCompanyId(), companyConfMap)
                );
                reportPropertiesList.add(
                        parseShenshiToPo((int) spo2 / count, "血氧", map, reportInfo.getReportId(), reportInfo.getCompanyId(), companyConfMap)
                );
            } else {
                reportPropertiesList.add(
                        parseShenshiToPo(0, "心率", map, reportInfo.getReportId(), reportInfo.getCompanyId(), companyConfMap)
                );
                reportPropertiesList.add(
                        parseShenshiToPo(0, "呼吸", map, reportInfo.getReportId(), reportInfo.getCompanyId(), companyConfMap)
                );
                reportPropertiesList.add(
                        parseShenshiToPo(0, "血压-收缩压", map, reportInfo.getReportId(), reportInfo.getCompanyId(), companyConfMap)
                );
                reportPropertiesList.add(
                        parseShenshiToPo(0, "血压-舒张压", map, reportInfo.getReportId(), reportInfo.getCompanyId(), companyConfMap)
                );
                reportPropertiesList.add(
                        parseShenshiToPo(0, "血氧", map, reportInfo.getReportId(), reportInfo.getCompanyId(), companyConfMap)
                );
            }

            updateDatabase(reportInfo, reportPropertiesList, 2);
        } catch (Exception e) {
            try {
                // 当作object解析
                FaceData faceData = JSONObject.parseObject(result, FaceData.class);
                // 保存结果
                Map<String, Long> map = getPropertiesListToMap();
                Map<Long, DefaultCompanyConf> companyConfMap = getDefaultCompanyConfMap();

                List<ReportProperties> reportPropertiesList = new ArrayList<>();
                reportPropertiesList.add(
                        parseShenshiToPo((int) faceData.getHr(), "心率", map, reportInfo.getReportId(), reportInfo.getCompanyId(), companyConfMap)
                );
                reportPropertiesList.add(
                        parseShenshiToPo((int) faceData.getBr(), "呼吸", map, reportInfo.getReportId(), reportInfo.getCompanyId(), companyConfMap)
                );
                reportPropertiesList.add(
                        parseShenshiToPo((int) faceData.getBp_h(), "血压-收缩压", map, reportInfo.getReportId(), reportInfo.getCompanyId(), companyConfMap)
                );
                reportPropertiesList.add(
                        parseShenshiToPo((int) faceData.getBp_l(), "血压-舒张压", map, reportInfo.getReportId(), reportInfo.getCompanyId(), companyConfMap)
                );
                reportPropertiesList.add(
                        parseShenshiToPo((int) faceData.getSpo2(), "血氧", map, reportInfo.getReportId(), reportInfo.getCompanyId(), companyConfMap)
                );

                updateDatabase(reportInfo, reportPropertiesList, 2);
            } catch (Exception e1) {
                throw new BizException(ErrorCode.SYSTEM_ERROR_JSON_PARSE_ERROR);
            }
        }

    }

    private Map<Long, DefaultCompanyConf> getDefaultCompanyConfMap() {
        // 获得参考值
        List<DefaultCompanyConf> defaultCompanyConfList = defaultCompanyConfMapper.selectList(null);
        return defaultCompanyConfList.stream()
                .collect(Collectors.toMap(DefaultCompanyConf::getDefaultCompanyConfId, it -> it));
    }

    @Override
    public IsAnalyzedVo isAnalyzed(String uuid) {
        ReportInfo reportInfo = reportInfoMapper.selectReportInfoByUuid(uuid);
        if (reportInfo == null) {
            throw new BizException(ErrorCode.SYSTEM_RESOURCE_ERROR_REPORT_NOT_EXISTS);
        }

        IsAnalyzedVo isAnalyzedVo = new IsAnalyzedVo();
        if (reportInfo.getStatus() == 3) {
            isAnalyzedVo.setIsVibraAnalyzed(true);
            isAnalyzedVo.setIsShenshiAnalyzed(true);
        } else if (reportInfo.getStatus() == 1) {
            isAnalyzedVo.setIsVibraAnalyzed(true);
            isAnalyzedVo.setIsShenshiAnalyzed(false);
        } else if (reportInfo.getStatus() == 2) {
            isAnalyzedVo.setIsVibraAnalyzed(false);
            isAnalyzedVo.setIsShenshiAnalyzed(true);
        } else {
            isAnalyzedVo.setIsVibraAnalyzed(false);
            isAnalyzedVo.setIsShenshiAnalyzed(false);
        }
        return isAnalyzedVo;
    }

    private ReportProperties parseShenshiToPo(Integer valueInt, String propertiesName, Map<String, Long> map, Long reportId, Long companyId, Map<Long, DefaultCompanyConf> companyConfMap) {
        ShenshiResultProperties result = ShenshiResultProperties.getPropertiesByTitle(propertiesName);
        DefaultCompanyConf defaultCompanyConf = companyConfMap.get(result.getDefaultCompanyConfIdOfValue());
        int compare = 0;
        if (defaultCompanyConf != null) {
            int lowerValueInt = 0;
            int upperValueInt = 0;
            // 如果是血压，则做特殊处理
            if (defaultCompanyConf.getDefaultCompanyConfId() == 37L) {
                // 血压-收缩压
                if (propertiesName.equals("血压-收缩压")) {
                    lowerValueInt = Integer.parseInt(defaultCompanyConf.getLowerValueString().split("/")[0]);
                    upperValueInt = Integer.parseInt(defaultCompanyConf.getUpperValueString().split("/")[0]);
                } else if (propertiesName.equals("血压-舒张压")) {
                    lowerValueInt = Integer.parseInt(defaultCompanyConf.getLowerValueString().split("/")[1]);
                    upperValueInt = Integer.parseInt(defaultCompanyConf.getUpperValueString().split("/")[1]);
                }
            } else {
                lowerValueInt = defaultCompanyConf.getLowerValueInt();
                upperValueInt = defaultCompanyConf.getUpperValueInt();
            }

            if (valueInt < lowerValueInt) {
                compare = 2;
            } else if (valueInt > upperValueInt) {
                compare = 1;
            }
        }
        return new ReportProperties(
                null,
                map.get(result.getDefaultCompanyConfId().toString()),
                reportId,
                companyId,
                valueInt,
                null,
                compare,
                1
        );
    }

    /**
     * @param type 1-Vibra 2-Shenshi
     */
    ReportInfo getReportInfo(String uuid, Integer type) {
        // 根据uuid 查询出reportInfo
        log.info("uuid: {}", uuid);
        ReportInfo reportInfo = reportInfoMapper.selectReportInfoByUuid(uuid);
        if (reportInfo == null) {
            log.info("需要分析的报告已被删除");
            return null;
            // throw new BizException(ErrorCode.SYSTEM_RESOURCE_ERROR_REPORT_NOT_EXISTS);
        }

        if (type == 1) {
            // Vibra
            if (reportInfo.getStatus() == 1 || reportInfo.getStatus() == 3) {
                throw new BizException(ErrorCode.SYSTEM_RESOURCE_ERROR_REPORT_VIBRA);
            }
        } else if (type == 2) {
            // Shenshi
            if (reportInfo.getStatus() == 2 || reportInfo.getStatus() == 3) {
                throw new BizException(ErrorCode.SYSTEM_RESOURCE_ERROR_REPORT_SHENSHI);
            }
        }
        return reportInfo;
    }

    /**
     * 更新数据库
     * @param type 1-Vibra 2-Shenshi
     */
    private void updateDatabase(ReportInfo reportInfo, List<ReportProperties> reportPropertiesList, Integer type) {
        // 去除空对象
        reportPropertiesList = reportPropertiesList.stream().filter(Objects::nonNull).collect(Collectors.toList());

        if (!reportPropertiesList.isEmpty()) {
            reportPropertiesMapper.insertBatchSomeColumn(reportPropertiesList);
        }
        if (reportInfo.getStatus() == 4) {
            // vibra 结果异常
            reportInfoMapper.updateById(reportInfo);
            return;
        }

        if (type == 1 && reportInfo.getStatus() == 0) {
            // 未分发 + Vibra -> Vibra
            reportInfo.setStatus(1);
            reportInfo.setVibraDate(new Date());
        } else if (type == 2 && reportInfo.getStatus() == 0) {
            // 未分发 + Shenshi -> Shenshi
            reportInfo.setStatus(2);
            reportInfo.setShenshiDate(new Date());
        } else if (type == 1 && reportInfo.getStatus() == 2) {
            // Shenshi + Vibra -> 已分发
            reportInfo.setStatus(3);
            reportInfo.setVibraDate(new Date());
            reportInfo.setReceiveDate(new Date());
            checkWarningType(reportInfo);
        } else if (type == 2 && reportInfo.getStatus() == 1) {
            // Vibra + Shenshi -> 已分发
            reportInfo.setStatus(3);
            reportInfo.setShenshiDate(new Date());
            reportInfo.setReceiveDate(new Date());
            checkWarningType(reportInfo);
        }

        reportInfoMapper.updateById(reportInfo);
    }

    private void checkWarningType(ReportInfo reportInfo) {
        // 检查是否有预警
        // 获取报告的指标值
        List<ReportPropertiesDto> reportPropertiesDtoList =
                reportPropertiesMapper.selectReportPropertiesDtoByReportId(reportInfo.getReportId());
        // 计算预警指标值的个数
        int warningCount = 0;
        for (ReportPropertiesDto reportPropertiesDto : reportPropertiesDtoList) {
            if (reportPropertiesDto.getCompare() != 0) {
                warningCount++;
            }
        }

        // 获得用户最近的report
        LambdaQueryWrapper<ReportInfo> reportInfoWrapper = new LambdaQueryWrapper<>();
        reportInfoWrapper.eq(ReportInfo::getUserId, reportInfo.getUserId());
        reportInfoWrapper.eq(ReportInfo::getStatus, 3);
        ArrayList<Integer> warningTypes = new ArrayList<Integer>();
        warningTypes.add(0);
        warningTypes.add(1);
        warningTypes.add(2);
        warningTypes.add(3);
        reportInfoWrapper.in(ReportInfo::getWarningType, warningTypes);
        reportInfoWrapper.notIn(ReportInfo::getReportId, reportInfo.getReportId());
        reportInfoWrapper.orderByDesc(ReportInfo::getReceiveDate);
        List<ReportInfo> reportInfoList = reportInfoMapper.selectList(reportInfoWrapper);

        // 用户的上次最新报告
        LambdaQueryWrapper<ReportInfo> lastReportWrapper = new LambdaQueryWrapper<>();
        lastReportWrapper.eq(ReportInfo::getUserId, reportInfo.getUserId());
        lastReportWrapper.eq(ReportInfo::getStatus, 3);
        reportInfoWrapper.notIn(ReportInfo::getReportId, reportInfo.getReportId());
        lastReportWrapper.orderByDesc(ReportInfo::getReceiveDate);
        lastReportWrapper.last("limit 1");
        ReportInfo lastReport = reportInfoMapper.selectOne(lastReportWrapper);

        // 获取预警相关的配置
        LambdaQueryWrapper<DefaultCompanyConf> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(DefaultCompanyConf::getDefaultCompanyConfId, 1L, 2L, 3L, 4L, 5L, 6L);
        List<DefaultCompanyConf> defaultCompanyConfList = defaultCompanyConfMapper.selectList(wrapper);
        Map<String, Integer> companyConfMap = defaultCompanyConfList.stream()
                .collect(Collectors.toMap(DefaultCompanyConf::getConfName, DefaultCompanyConf::getLowerValueInt));

        // 连续 companyConfMap.get("应答性预警阈值") 有异常则设置 warningType = 1
        // 连续 companyConfMap.get("适应性预警阈值") 有异常则设置 warningType = 2
        // 连续 companyConfMap.get("风险性预警阈值") 有异常则设置 warningType = 3
        // 连续 companyConfMap.get("应答性预警取消阈值") 无异常则设置 warningType = 2
        // 连续 companyConfMap.get("适应性预警取消阈值") 无异常则设置 warningType = 1
        // 连续 companyConfMap.get("风险性预警取消阈值") 无异常则设置 warningType = 0

        int warningType = 0;
        boolean cancelWarning = true;
        // 本次报告有异常
        log.info("本次报告有异常");
        Integer count1 = companyConfMap.get("应答性预警阈值");
        Integer count2 = companyConfMap.get("适应性预警阈值");
        Integer count3 = companyConfMap.get("风险性预警阈值");
        if (warningCount > 0) {
            // 先统计已经连续几次报预警了
            boolean isWarning = true;
            // 与上一次报告做对比
            if (!reportInfoList.isEmpty() && reportInfoList.get(0) != null) {
                // 获取上一次预警
                ReportInfo info = reportInfoList.get(0);
                switch (info.getWarningType()) {
                    case 0:
                        for (int i = 0; i < count1-1; i++) {
                            if (reportInfoList.get(i).getHasAbnormality() == 0 ||
/*
                                    reportInfoList.get(i).getWarningType() != 0 ||
*/
                                    i == reportInfoList.size() - 1) {
                                log.info("不是连续{}次的应答性预警阈值，则不升级", companyConfMap.get("应答性预警阈值"));
                                isWarning = false;
                                break;
                            }
                        }
                        if (isWarning) {
                            // 预警升级
                            warningType = 1;
                        } else {
                            warningType = info.getWarningType();
                        }
                        break;
                    case 1:
                        for (int i = 0; i < count2; i++) {
                            if (reportInfoList.get(i).getHasAbnormality() == 0 ||
/*
                                    reportInfoList.get(i).getWarningType() != 1 ||
*/
                                    i == reportInfoList.size() - 1) {
                                // 不是连续的预警，则不升级
                                log.info("不是连续{}次的适应性预警阈值，则不升级", count2);
                                isWarning = false;
                                break;
                            }
                        }
                        if (isWarning) {
                            warningType = 2;
                        } else {
                            warningType = info.getWarningType();
                        }
                        break;
                    case 2:
                        for (int i = 0; i < count3; i++) {
                            if (reportInfoList.get(i).getHasAbnormality() == 0 ||
/*
                                    reportInfoList.get(i).getWarningType() != 2 ||
*/
                                    i == reportInfoList.size() - 1) {
                                // 不是连续的相同预警，则不升级
                                log.info("不是连续的风险性预警阈值，则不升级");
                                isWarning = false;
                                break;
                            }
                        }
                        if (isWarning) {
                            warningType = 3;
                        } else {
                            warningType = info.getWarningType();
                        }
                        break;
                    case 3:
                        warningType = 3;
                        break;
                    default:
                        throw new BizException(ErrorCode.SYSTEM_ERROR_REPORT_WARNING_TYPE_ERROR);
                }
            } else {
                // 本次是该用户的第一次报告，如果companyConfMap.get("应答性预警阈值") = 1则设置为应答性预警
                if (count1 <= 1) {
                    warningType = 1;
                }
            }
            reportInfo.setHasAbnormality(1);
        }
        // 本次报告无异常
        else {
            // 与上一次报告做对比
            if (!reportInfoList.isEmpty() && reportInfoList.get(0) != null) {
                ReportInfo info = reportInfoList.get(0);
                switch (info.getWarningType()) {
                    // 上一次也无预警
                    case 0:
                        break;
                    // 上一次是应答性预警
                    case 1:
                        warningType = 1;
                        for (int i = 0; i < count1 - 1; i++) {
                            if (reportInfoList.get(i).getHasAbnormality() == 1 ||
/*
                                    reportInfoList.get(i).getWarningType() != 1 ||
*/
                                    i == reportInfoList.size() - 1) {
                                // 不是连续无异常，则不取消预警
                                log.info("不是连续{}次的应答性预警取消阈值，则不取消预警", count1);
                                cancelWarning = false;
                                break;
                            }
                        }
                        break;
                    // 上一次是适应性预警
                    case 2:
                        warningType = 2;
                        for (int i = 0; i < count2 - 1; i++) {
                            if (reportInfoList.get(i).getHasAbnormality() == 1 ||
/*
                                    reportInfoList.get(i).getWarningType() != 2 ||
*/
                                    i == reportInfoList.size() - 1) {
                                // 不是连续无异常，则不取消预警
                                log.info("不是连续{}次的适应性预警取消阈值，则不取消预警", count2);
                                cancelWarning = false;
                                break;
                            }
                        }
                        break;
                    // 上一次是风险性预警
                    case 3:
                        warningType = 3;
                        for (int i = 0; i < companyConfMap.get("风险性预警取消阈值"); i++) {
                            if (reportInfoList.get(i).getHasAbnormality() == 1 ||
/*
                                    reportInfoList.get(i).getWarningType() != 3 ||
*/
                                    i == reportInfoList.size() - 1) {
                                // 不是连续无异常，则不取消预警
                                log.info("不是连续{}次的风险性预警取消阈值，则不取消预警", companyConfMap.get("风险性预警取消阈值"));
                                cancelWarning = false;
                                break;
                            }
                        }
                        break;
                    default:
                        throw new BizException(ErrorCode.SYSTEM_ERROR_REPORT_WARNING_TYPE_ERROR);
                }
                if (cancelWarning) {
                    warningType = warningType - 1;
                } else {
                    warningType = info.getWarningType();
                }
            }
            // 本次是该用户的第一次报告，则正常按无预警处理
            reportInfo.setHasAbnormality(0);
        }

        reportInfo.setWarningType(warningType);

        if (lastReport == null) {
            if (warningType == 1) {
                reportInfo.setResponseWarningCount(1);
            } else if (warningType == 2) {
                reportInfo.setAdaptiveWarningCount(1);
            } else if (warningType == 3) {
                reportInfo.setRiskWarningCount(1);
            }
        } else {
            if (warningCount == 0) {
                if (cancelWarning) {
                    // 本次报告没有异常，且可以取消预警
                    log.info("本次报告没有异常，且可以取消预警，设置所有预警值为0");
                    reportInfo.setResponseWarningCount(0);
                    reportInfo.setAdaptiveWarningCount(0);
                    reportInfo.setRiskWarningCount(0);
                } else {
                    // 本次报告没有异常，但不取消的状态
                    reportInfo.setResponseWarningCount(lastReport.getResponseWarningCount());
                    reportInfo.setAdaptiveWarningCount(lastReport.getAdaptiveWarningCount());
                    reportInfo.setRiskWarningCount(lastReport.getRiskWarningCount());
                }
            } else if (warningType == 1) {
                reportInfo.setResponseWarningCount(lastReport.getResponseWarningCount() + 1);
            } else if (warningType == 2) {
                reportInfo.setAdaptiveWarningCount(lastReport.getAdaptiveWarningCount() + 1);
            } else if (warningType == 3) {
                reportInfo.setRiskWarningCount(lastReport.getRiskWarningCount() + 1);
            }
        }

        log.info("报告的预警类型为: {}", warningType);
        reportInfoMapper.updateById(reportInfo);
    }
}
